package com.jnzc.ocr.serv.shop.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import com.jnzc.ocr.common.consts.PayConsts;
import com.jnzc.ocr.common.error.BusinessException;
import com.jnzc.ocr.common.utils.CalculateUtils;
import com.jnzc.ocr.common.utils.DateUtils;
import com.jnzc.ocr.common.utils.ValidateUtils;
import com.jnzc.ocr.dependencies.serv.mybatis.MybatisServiceImpl;
import com.jnzc.ocr.serv.shop.consts.ShopOrderConsts;
import com.jnzc.ocr.serv.shop.entity.ShopMember;
import com.jnzc.ocr.serv.shop.entity.ShopOrder;
import com.jnzc.ocr.serv.shop.entity.ShopOrderRecharge;
import com.jnzc.ocr.serv.shop.entity.ShopOrderSaleDetail;
import com.jnzc.ocr.serv.shop.filter.ShopOrderFilter;
import com.jnzc.ocr.serv.shop.mapper.ShopOrderMapper;
import com.jnzc.ocr.serv.shop.service.*;
import com.jnzc.ocr.serv.shop.vo.ShopOrderPayVo;
import com.jnzc.ocr.serv.shop.vo.ShopProductStockChangeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author zhangcm
 * @version 1.0, 2017-10-06
 */
@Service
public class ShopOrderServiceImpl extends MybatisServiceImpl<ShopOrderMapper, ShopOrder, ShopOrderFilter> implements ShopOrderService {

    @Autowired
    private ShopOrderSaleService shopOrderSaleService;

    @Autowired
    private ShopOrderRechargeService shopOrderRechargeService;

    @Autowired
    private ShopMemberService shopMemberService;

    @Autowired
    private ShopOrderSaleDetailService shopOrderSaleDetailService;

    @Autowired
    private ShopProductStockService shopProductStockService;

    @Override
    protected void fillEntityWrapper(EntityWrapper<ShopOrder> ew, ShopOrderFilter filter) {
        ShopOrder entity = new ShopOrder();
        entity.setId(filter.getId());
        entity.setShopId(filter.getShopId());
        entity.setMemberId(filter.getMemberId());
        entity.setType(filter.getType());
        entity.setState(filter.getState());
        entity.setIfRefund(filter.getIfRefund());
        ew.setEntity(entity);
        if(null != filter.getBeginFinishTime()) {
            ew.ge("finish_time", filter.getBeginFinishTime());
        }
        if(null != filter.getEndFinishTime()) {
            ew.lt("finish_time", filter.getEndFinishTime());
        }
    }

    @Override
    public ShopOrder find(Long id, Long shopId) {
        ValidateUtils.isId(id);
        ShopOrderFilter filter = new ShopOrderFilter();
        filter.setId(id);
        filter.setShopId(shopId);
        return super.findNotNull(filter);
    }

    @Override
    @Transactional
    public ShopOrder pay(ShopOrderPayVo payVo) {
        ValidateUtils.isId(payVo.getOrderId(), "订单ID");
        ValidateUtils.in(payVo.getPayType(), PayConsts.PAY_TYPE_LIST, "支付方式");
        ShopOrder order = this.find(payVo.getOrderId(), payVo.getShopId());
        if(ShopOrderConsts.STATE_UNPAY != order.getState()) {
            throw new BusinessException("订单已付款");
        }
        if(ShopOrderConsts.TYPE_SALE == order.getType()){
            paySale(order, payVo);
        } else if(ShopOrderConsts.TYPE_RECHARGE == order.getType()){
            payRecharge(order, payVo);
        } else {
            throw new BusinessException("订单不支持支付");
        }
        return order;
    }

    private void paySale(ShopOrder order, ShopOrderPayVo payVo){
        ShopMember member = null;
        if(null != order.getMemberId()){
            member = shopMemberService.find(order.getMemberId(), order.getShopId());
        }
        if(PayConsts.PAY_TYPE_CASH == payVo.getPayType()) {
            // 无操作
        } else if(PayConsts.PAY_TYPE_BALANCE == payVo.getPayType()) {
            ValidateUtils.isTrue(null != order.getMemberId(), "非会员订单，无法使用余额支付");
            shopMemberService.update(member, CalculateUtils.neg(order.getAmount()), null, null, false);
        } else {
            throw new BusinessException("订单不支持该支付方式");
        }
        order.setState(ShopOrderConsts.STATE_FINISH);
        order.setPayType(payVo.getPayType());
        order.setPayTime(DateUtils.getNow());
        order.setFinishTime(DateUtils.getNow());
        this.updateOne(order);
        // 更新用户余额、积分和消费金额
        if(null != member){
            shopMemberService.update(member, null, order.getAddPoint(), order.getAmount());
        }
        // 更新库存
        List<ShopOrderSaleDetail> detailList = shopOrderSaleDetailService.list(order.getId());
        List<ShopProductStockChangeVo> changeList = Lists.newArrayList();
        for (ShopOrderSaleDetail detail : detailList) {
            ShopProductStockChangeVo change = new ShopProductStockChangeVo();
            change.setProductId(detail.getProductId());
            change.setSkuId(detail.getSkuId());
            change.setAddStockNum(CalculateUtils.neg(detail.getNum()));
            change.setAddSaleNum(detail.getNum());
            changeList.add(change);
        }
        shopProductStockService.updateNum(changeList, order.getShopId());
    }

    private void payRecharge(ShopOrder order, ShopOrderPayVo payVo){
        ShopOrderRecharge recharge = shopOrderRechargeService.find(order.getId(), order.getShopId());
        ShopMember member = shopMemberService.find(order.getMemberId(), order.getShopId());
        if(PayConsts.PAY_TYPE_CASH == payVo.getPayType()) {
            // 无操作
        } else {
            throw new BusinessException("订单不支持该支付方式");
        }
        order.setState(ShopOrderConsts.STATE_FINISH);
        order.setPayType(payVo.getPayType());
        order.setPayTime(DateUtils.getNow());
        order.setFinishTime(DateUtils.getNow());
        this.updateOne(order);
        // 更新用户余额、积分
        shopMemberService.update(member, recharge.getRechargeAmount(), order.getAddPoint(), null);
    }
}
